Import all debian/ directory changes from master
authorDominique Belhachemi <domibel@debian.org>
Tue, 23 Sep 2025 21:36:03 +0000 (17:36 -0400)
committerDominique Belhachemi <domibel@debian.org>
Tue, 23 Sep 2025 21:36:03 +0000 (17:36 -0400)
13 files changed:
debian/changelog
debian/control
debian/copyright
debian/libvtk9.1t64-qt.lintian-overrides [new file with mode: 0644]
debian/libvtk9.1t64.lintian-overrides [new file with mode: 0644]
debian/patches/09_newer_expat.patch [new file with mode: 0644]
debian/patches/100_add_missing_gl_header.patch
debian/patches/121_add_support_for_loong64.patch [new file with mode: 0644]
debian/patches/130_fix_python_3.13.patch [new file with mode: 0644]
debian/patches/42_fix_octree_node.patch [new file with mode: 0644]
debian/patches/netcdf-4.9.3.patch [new file with mode: 0644]
debian/patches/series
debian/rules

index 953790f121cb79bb32ea4721d6dc774b139db239..f8e488d031212f963a039fddbe305aec3fbe9bdb 100644 (file)
@@ -4,6 +4,119 @@ vtk9 (9.5.2+dfsg1-1~exp1) UNRELEASED; urgency=medium
 
  -- Dominique Belhachemi <domibel@debian.org>  Tue, 23 Sep 2025 16:48:13 -0400
 
+vtk9 (9.3.0+dfsg1-7) unstable; urgency=medium
+
+  * Non-maintainer upload
+  * Remove obsolete libosmesa6-dev dependency. (Closes: #1113920)
+  * Remove obsolete tcl-dev and tk-dev dependency.
+  * Remove r-base dependency
+  * Apply upstream patch to fix gcc-15 FTBFS issue (Closes: #1111572)
+  * Remove obsolete libftgl-dev dependency
+
+ -- Dominique Belhachemi <domibel@debian.org>  Thu, 04 Sep 2025 14:06:08 -0400
+
+vtk9 (9.3.0+dfsg1-6) unstable; urgency=medium
+
+  * Team upload.
+  * Remove obsolete libmrmpi-dev dependency.
+
+ -- Bastian Germann <bage@debian.org>  Mon, 01 Sep 2025 17:22:13 +0200
+
+vtk9 (9.3.0+dfsg1-5) unstable; urgency=medium
+
+  * Team upload.
+  [ Adrian Bunk ]
+  * Apply patch from Samuel Thibault to disable Java and TBB on Hurd.
+    Closes: #1094994.
+  * Make TBB architecture settings consistent.
+  * Remove handling of removed kfreebsd.
+
+ -- Santiago Vila <sanvila@debian.org>  Fri, 22 Aug 2025 13:20:00 +0200
+
+vtk9 (9.3.0+dfsg1-4) unstable; urgency=medium
+
+  * Team upload.
+  * Replace _FillValue by NC_FillValue for NetCDF 4.9.3. (Closes: #1095478)
+
+ -- Bastian Germann <bage@debian.org>  Sat, 15 Feb 2025 13:13:19 +0000
+
+vtk9 (9.3.0+dfsg1-3) unstable; urgency=medium
+
+  * [a52f6c5] Fix segfault on python 3.13. (Closes: #1092354)
+
+ -- Anton Gladky <gladk@debian.org>  Tue, 28 Jan 2025 21:40:49 +0100
+
+vtk9 (9.3.0+dfsg1-2) unstable; urgency=medium
+
+  * Team upload.
+  * Drop Depends: libqt5webkit5-dev.
+
+ -- Bastian Germann <bage@debian.org>  Thu, 23 Jan 2025 08:49:29 +0100
+
+vtk9 (9.3.0+dfsg1-1.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Build against libhdf5-mpi-dev, since libhdf5-openmpi-dev is no longer
+    available on 32-bit architectures. Closes: #1078743.
+
+ -- Emilio Pozuelo Monfort <pochu@debian.org>  Fri, 22 Nov 2024 11:49:45 +0100
+
+vtk9 (9.3.0+dfsg1-1) unstable; urgency=medium
+
+  * Team upload.
+
+  [ Michael R. Crusoe ]
+  * Build the IO/GeoJSON module. Closes: #1029285
+    To the binary package libvtk9.1t64, this adds
+      /usr/lib/${DEB_HOST_MULTIARCH}/libvtkIOGeoJSON-9.1.so.9.1.0
+      /usr/lib/${DEB_HOST_MULTIARCH}/vtk/hierarchy/VTK/vtkIOGeoJSON-hierarchy.txt
+      /usr/lib/${DEB_HOST_MULTIARCH}/libvtkIOGeoJSON-9.1.so.1
+    To the binary package libvtk9-dev, this adds
+      /usr/include/vtk-9.1/vtkGeoJSONFeature.h
+      /usr/include/vtk-9.1/vtkGeoJSONReader.h
+      /usr/include/vtk-9.1/vtkGeoJSONWriter.h
+      /usr/include/vtk-9.1/vtkIOGeoJSONModule.h
+      /usr/lib/${DEB_HOST_MULTIARCH}/libvtkIOGeoJSON-9.1.so
+    To the binary package libvtk9-java, this adds
+      /usr/lib/${DEB_HOST_MULITARCH}/java/vtk-Linux-${DEB_HOST_GNU_CPU}
+        /libvtkIOGeoJSONJava.so
+    To the binary package python3-vtk9, this adds
+      /usr/lib/python3/dist-packages/vtkmodules
+        /vtkIOGeoJSON.cpython-311-${DEB_HOST_GNU_CPU}.so
+
+  [ Anton Gladky ]
+  * Upload of new version 9.3 into unstable.
+
+ -- Anton Gladky <gladk@debian.org>  Thu, 06 Jun 2024 21:34:35 +0200
+
+vtk9 (9.1.0+really9.1.0+dfsg2-8) unstable; urgency=medium
+
+  [ Bo YU ]
+  * Team upload.
+  * Add support for loongarch64. Thanks to Dandan Zhang
+    <zhangdandan@loongson.cn>. (Closes: #1054471)
+
+  [ Michael R. Crusoe ]
+  * Cherry-pick patch from upstream to fix issue with newer expat and
+    appended data. Closes: #1064762
+  * d/control: build-dep on libhdf5-mpi-dev instead of libhdf5-openmpi-
+    dev. Closes: #1068321
+  * Cherry-pick patch from upstream to fix CVE-2021-42521. Closes:
+    #1031877.
+  * Fix Maintainer name of Debian Science team (routine-update)
+  * Remove trailing whitespace in debian/copyright (routine-update)
+  * d/control: Updated some dependencies on obsolete or supercede packages
+    names.
+
+ -- Michael R. Crusoe <crusoe@debian.org>  Mon, 29 Apr 2024 16:16:28 +0200
+
+vtk9 (9.1.0+really9.1.0+dfsg2-7.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Rename libraries for 64-bit time_t transition.  Closes: #1063267
+
+ -- Steve Langasek <vorlon@debian.org>  Wed, 28 Feb 2024 23:38:25 +0000
+
 vtk9 (9.3.0+dfsg1-1~exp4) experimental; urgency=medium
 
   * [43fb8c1] Add libgl2ps-dev as depends.
index 44b19d6ea2e204d9456f8cf603329f739946f181..b0f1c287bf649747b6c3140152c1aaac8f6b4d5d 100644 (file)
@@ -1,14 +1,15 @@
 Source: vtk9
-Maintainer: Debian Science Team <debian-science-maintainers@lists.alioth.debian.org>
+Maintainer: Debian Science Maintainers <debian-science-maintainers@lists.alioth.debian.org>
 Uploaders: Anton Gladky <gladk@debian.org>,
            Gert Wollny <gewo@debian.org>,
            Nico Schlömer <nico.schloemer@gmail.com>
 Section: graphics
 Priority: optional
-Build-Depends: chrpath,
-               cmake (>= 3.2.0),
+Build-Depends: dpkg-dev (>= 1.22.5),
+               chrpath,
+               cmake,
                debhelper-compat (= 13),
-               default-jdk [!hppa !hurd-any !kfreebsd-any],
+               default-jdk [!hppa !hurd-any],
                default-libmysqlclient-dev,
                dh-sequence-python3,
                doxygen-latex,
@@ -28,22 +29,19 @@ Build-Depends: chrpath,
                libexpat-dev,
                libfontconfig-dev,
                libfreetype-dev,
-               libftgl-dev,
                libgdal-dev,
-               libgl1-mesa-dev | libgl-dev,
+               libgl-dev,
                libgl2ps-dev,
                libglew-dev,
-               libglu1-mesa-dev | libglu-dev,
-               libhdf5-openmpi-dev,
+               libglu-dev,
+               libhdf5-mpi-dev,
                libhpdf-dev,
                libjpeg-dev,
                libjs-mathjax,
                libjsoncpp-dev,
                liblz4-dev,
-               libmrmpi-dev,
                libnetcdf-dev (>= 1:4.9.0),
                libogg-dev,
-               libosmesa6-dev,
                libpng-dev,
                libpq-dev,
                libproj-dev,
@@ -60,19 +58,14 @@ Build-Depends: chrpath,
                libxt-dev,
                lzma,
                mpi-default-dev,
-               pkg-config,
+               pkgconf,
                python3-dev,
                python3-matplotlib,
                python3-mpi4py,
                qtbase5-dev,
                libqt5opengl5-dev,
                qtdeclarative5-dev,
-               r-base-core,
-               r-base-dev,
-               r-base,
-               tcl-dev,
                texlive-binaries,
-               tk-dev,
                x11proto-core-dev,
                xauth,
                xvfb,
@@ -86,10 +79,11 @@ Rules-Requires-Root: no
 
 Package: libvtk9-dev
 Architecture: any
+Multi-Arch: same
 Section: libdevel
 Depends: ${misc:Depends},
          ${shlibs:Depends},
-         default-jdk [!hppa !hurd-any !kfreebsd-any],
+         default-jdk [!hppa !hurd-any],
          default-libmysqlclient-dev,
          libavcodec-dev,
          libavformat-dev,
@@ -115,12 +109,12 @@ Depends: ${misc:Depends},
          libproj-dev,
          libpython3-dev,
          libswscale-dev,
-         libtbb-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64 !alpha !ia64],
+         libtbb-dev [linux-any],
          libtheora-dev,
          libtiff-dev,
          libutfcpp-dev,
          libvtk9.3 (= ${binary:Version}),
-         libvtk9-java (= ${binary:Version}) [!hppa !hurd-any !kfreebsd-any],
+         libvtk9-java (= ${binary:Version}) [!hppa !hurd-any],
          libx11-dev,
          libxft-dev,
          libxml2-dev,
@@ -128,8 +122,6 @@ Depends: ${misc:Depends},
          libxt-dev,
          mpi-default-dev,
          python3-vtk9 (= ${binary:Version}),
-         tcl-dev,
-         tk-dev,
          vtk9 (= ${binary:Version}),
          x11proto-core-dev,
          zlib1g-dev
@@ -146,13 +138,16 @@ Package: libvtk9.3
 Architecture: any
 Multi-Arch: same
 Section: libs
-Breaks: libvtk9 (<< 9.1.0+really9.1.0)
-Replaces: libvtk9 (<< 9.1.0+really9.1.0)
 Depends: ${misc:Depends},
          ${shlibs:Depends}
 Suggests: mpi-default-bin,
           vtk9-doc,
           vtk9-examples
+Breaks: libvtk9.1 (<< ${source:Version}),
+        libvtk9 (<< 9.1.0+really9.1.0)
+Provides: ${t64:Provides}
+Replaces: libvtk9.1,
+          libvtk9 (<< 9.1.0+really9.1.0)
 Description: VTK libraries
  The Visualization Toolkit (VTK) is an open-source software system
  for 3D computer graphics, image processing, and visualization.
@@ -161,7 +156,7 @@ Description: VTK libraries
  that use VTK.
 
 Package: libvtk9-java
-Architecture: amd64 arm64 armel armhf i386 mips64el mipsel ppc64el s390x alpha ia64 m68k powerpc ppc64 riscv64 sh4 sparc64 x32
+Architecture: amd64 arm64 armel armhf i386 loong64 mips64el mipsel ppc64el s390x alpha ia64 m68k powerpc ppc64 riscv64 sh4 sparc64 x32
 Section: java
 Depends: ${java:Depends},
          ${misc:Depends},
@@ -173,7 +168,7 @@ Suggests: java-virtual-machine,
           vtk9-examples
 Description: VTK - Java language support
  The Visualization Toolkit (VTK) is an object oriented, high level
- library that allows one to easily write C++ programs, Tcl, Python and
+ library that allows one to easily write C++ programs, Python and
  Java scripts that do 3D visualization.
  .
  This package provides the VTK Java language support.
@@ -248,12 +243,16 @@ Multi-Arch: same
 Section: libs
 Depends: ${misc:Depends},
          ${shlibs:Depends}
+Breaks: libvtk9.1-qt (<< ${source:Version})
+Provides: ${t64:Provides}
+Replaces: libvtk9.1-qt
 Description: VTK libraries, Qt files
  The Visualization Toolkit (VTK) is an open-source software system
  for 3D computer graphics, image processing, and visualization.
  .
  This package provides the shared libraries needed to run C++ programs
  that use VTK. Qt files
+X-Time64-Compat: libvtk9.1-qt
 
 Package: libvtk9-qt-dev
 Architecture: any
@@ -266,7 +265,6 @@ Depends: libvtk9-dev (= ${binary:Version}),
          qtbase5-dev,
          qttools5-private-dev,
          libqt5opengl5-dev,
-         libqt5webkit5-dev
 Description: VTK header files, containing Qt files
  The Visualization Toolkit (VTK) is an open-source software system
  for 3D computer graphics, image processing, and visualization.
index d0fe9287f82ce07519e2345f7bbcfdeab06974d9..b3597407182663270a1cd44e4bf34e6027907f5d 100644 (file)
@@ -272,18 +272,18 @@ License: Apache-2
 License: Zlib
   This software is provided 'as-is', without any express or implied warranty.
   .
-  In no event will the authors be held liable for any damages arising from the 
+  In no event will the authors be held liable for any damages arising from the
   use of this software.
   .
-  Permission is granted to anyone to use this software for any purpose,including 
-  commercial applications, and to alter it and redistribute it freely, subject 
+  Permission is granted to anyone to use this software for any purpose,including
+  commercial applications, and to alter it and redistribute it freely, subject
   to the following restrictions:
   .
-  1. The origin of this software must not be misrepresented; you must not claim 
-      that you wrote the original software. If you use this software in a 
-      product, an acknowledgment in the product documentation would be 
+  1. The origin of this software must not be misrepresented; you must not claim
+      that you wrote the original software. If you use this software in a
+      product, an acknowledgment in the product documentation would be
       appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be 
+  2. Altered source versions must be plainly marked as such, and must not be
       misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 
diff --git a/debian/libvtk9.1t64-qt.lintian-overrides b/debian/libvtk9.1t64-qt.lintian-overrides
new file mode 100644 (file)
index 0000000..b0273f5
--- /dev/null
@@ -0,0 +1,2 @@
+libvtk9.1t64-qt: package-name-doesnt-match-sonames
+libvtk9.1t64-qt: package-name-doesnt-match-sonames libvtk9.1-qt
diff --git a/debian/libvtk9.1t64.lintian-overrides b/debian/libvtk9.1t64.lintian-overrides
new file mode 100644 (file)
index 0000000..d9ce053
--- /dev/null
@@ -0,0 +1,2 @@
+libvtk9.1t64: package-name-doesnt-match-sonames
+libvtk9.1t64: package-name-doesnt-match-sonames libvtk9.1
diff --git a/debian/patches/09_newer_expat.patch b/debian/patches/09_newer_expat.patch
new file mode 100644 (file)
index 0000000..0e66e40
--- /dev/null
@@ -0,0 +1,68 @@
+From: Ben Boeckel <ben.boeckel@kitware.com>
+Date: Mon, 15 Apr 2024 22:22:22 -0400
+Subject: vtkXMLDataParser: track `AppendedData` state explicitly
+Bug-Debian: https://bugs.debian.org/1064762
+Origin: upstream,https://gitlab.kitware.com/vtk/vtk/-/commit/3efa07ad277efe5c1d11a2ef2b907c095f68bbef
+Forwarded: not-needed
+
+Newer `libexpat` doesn't like being given the appended data after the
+artificially ended document anymore. Avoid pushing it through to its
+parser.
+
+---
+ IO/XMLParser/vtkXMLDataParser.cxx | 6 +++++-
+ IO/XMLParser/vtkXMLDataParser.h   | 3 +++
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+Index: vtk9/IO/XMLParser/vtkXMLDataParser.cxx
+===================================================================
+--- vtk9.orig/IO/XMLParser/vtkXMLDataParser.cxx
++++ vtk9/IO/XMLParser/vtkXMLDataParser.cxx
+@@ -36,6 +36,7 @@ vtkXMLDataParser::vtkXMLDataParser()
+   this->RootElement = nullptr;
+   this->AppendedDataPosition = 0;
+   this->AppendedDataMatched = 0;
++  this->AppendedDataFound = false;
+   this->DataStream = nullptr;
+   this->InlineDataStream = vtkBase64InputStream::New();
+   this->AppendedDataStream = vtkBase64InputStream::New();
+@@ -88,6 +89,7 @@ void vtkXMLDataParser::PrintSelf(ostream
+ {
+   this->Superclass::PrintSelf(os, indent);
+   os << indent << "AppendedDataPosition: " << this->AppendedDataPosition << "\n";
++  os << indent << "AppendedDataFound: " << this->AppendedDataFound << "\n";
+   if (this->RootElement)
+   {
+     this->RootElement->PrintXML(os, indent);
+@@ -214,7 +216,7 @@ int vtkXMLDataParser::ParsingComplete()
+   // If we have reached the appended data section, we stop parsing.
+   // This prevents the XML parser from having to walk over the entire
+   // appended data section.
+-  if (this->AppendedDataPosition)
++  if (this->AppendedDataPosition || this->AppendedDataFound)
+   {
+     return 1;
+   }
+@@ -433,6 +435,8 @@ int vtkXMLDataParser::ParseBuffer(const
+     {
+       return 0;
+     }
++
++    this->AppendedDataFound = true;
+   }
+   return 1;
+Index: vtk9/IO/XMLParser/vtkXMLDataParser.h
+===================================================================
+--- vtk9.orig/IO/XMLParser/vtkXMLDataParser.h
++++ vtk9/IO/XMLParser/vtkXMLDataParser.h
+@@ -204,6 +204,9 @@ protected:
+   // How much of the string "<AppendedData" has been matched in input.
+   int AppendedDataMatched;
++  // Whether AppendedData has been dealt with or not.
++  bool AppendedDataFound;
++
+   // The byte order of the binary input.
+   int ByteOrder;
index e1d71986dbb4f596879b01a5f2b304b58d112635..13b2a1c24edc3f3980a61dbfe77166469f576c49 100644 (file)
@@ -1,27 +1,5 @@
-Description: <short summary of the patch>
- TODO: Put a short summary on the line above and replace this paragraph
- with a longer explanation of this change. Complete the meta-information
- with other relevant fields (see below for details). To make it easier, the
- information below has been extracted from the changelog. Adjust it or drop
- it.
- .
- vtk9 (9.3.0+dfsg1-1~exp2) experimental; urgency=medium
- .
-   * [ad5a07d] Update build-depends.
+Description: Add missing GL header
 Author: Anton Gladky <gladk@debian.org>
-
----
-The information above should follow the Patch Tagging Guidelines, please
-checkout https://dep.debian.net/deps/dep3/ to learn about the format. Here
-are templates for supplementary fields that you might want to add:
-
-Origin: (upstream|backport|vendor|other), (<patch-url>|commit:<commit-id>)
-Bug: <upstream-bugtracker-url>
-Bug-Debian: https://bugs.debian.org/<bugnumber>
-Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
-Forwarded: (no|not-needed|<patch-forwarded-url>)
-Applied-Upstream: <version>, (<commit-url>|commit:<commid-id>)
-Reviewed-By: <name and email of someone who approved/reviewed the patch>
 Last-Update: 2024-01-10
 
 --- vtk9-9.3.0+dfsg1.orig/GUISupport/Qt/QVTKOpenGLWindow.cxx
diff --git a/debian/patches/121_add_support_for_loong64.patch b/debian/patches/121_add_support_for_loong64.patch
new file mode 100644 (file)
index 0000000..ee9fbea
--- /dev/null
@@ -0,0 +1,22 @@
+Description: add support for loongarch64 
+Upstream:  https://gitlab.kitware.com/seanm/vtk/-/commit/886b536a0d0bb3694951e09169a52896d585c517
+Author: Dandan Zhang <zhangdandan@loongson.cn>
+
+---
+Last-Update: 2023-10-24
+
+Index: VTK-9.3.0/Utilities/KWIML/vtkkwiml/include/kwiml/abi.h
+===================================================================
+--- VTK-9.3.0.orig/Utilities/KWIML/vtkkwiml/include/kwiml/abi.h
++++ VTK-9.3.0/Utilities/KWIML/vtkkwiml/include/kwiml/abi.h
+@@ -413,6 +413,10 @@ suppression macro KWIML_ABI_NO_VERIFY wa
+ #elif defined(__loongarch64)
+ # define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
++/* LoongArch */
++#elif defined(__loongarch64)
++# define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_LITTLE
++
+ /* Motorola 68k */
+ #elif defined(__m68k__) || defined(M68000)
+ # define KWIML_ABI_ENDIAN_ID KWIML_ABI_ENDIAN_ID_BIG
diff --git a/debian/patches/130_fix_python_3.13.patch b/debian/patches/130_fix_python_3.13.patch
new file mode 100644 (file)
index 0000000..31641fd
--- /dev/null
@@ -0,0 +1,1058 @@
+Description: Fix python 3.13 segfault
+Author: Anton Gladky <gladk@debian.org>
+Bug-Debian: https://bugs.debian.org/1092354
+Applied-Upstream: https://gitlab.kitware.com/vtk/vtk/-/merge_requests/11486 ; https://gitlab.kitware.com/vtk/vtk/-/merge_requests/11486
+Last-Update: 2025-01-28
+
+--- vtk9-9.3.0+dfsg1.orig/Utilities/PythonInterpreter/vtkPythonInterpreter.cxx
++++ vtk9-9.3.0+dfsg1/Utilities/PythonInterpreter/vtkPythonInterpreter.cxx
+@@ -96,6 +96,7 @@ wchar_t* vtk_Py_UTF8ToWide(const char* a
+   return result;
+ }
++#if PY_VERSION_HEX < 0x03080000
+ std::string vtk_Py_WideToUTF8(const wchar_t* arg)
+ {
+   std::string result;
+@@ -109,6 +110,7 @@ std::string vtk_Py_WideToUTF8(const wcha
+   return result;
+ }
++#endif
+ std::vector<vtkWeakPointer<vtkPythonInterpreter>>* GlobalInterpreters;
+ std::vector<std::string> PythonPaths;
+@@ -333,12 +335,21 @@ void SetupVTKPythonPaths(bool isolated)
+   if (vtklib.empty())
+   {
+     VTKPY_DEBUG_MESSAGE(
+-      "`GetVTKVersion` library couldn't be found. Will use `Py_GetProgramName` next.");
++      "`GetVTKVersion` library couldn't be found. Will use `sys.executable` next.");
+   }
+   if (vtklib.empty())
+   {
++#if PY_VERSION_HEX >= 0x03080000
++    vtkPythonScopeGilEnsurer gilEnsurer;
++    PyObject* executable_path = PySys_GetObject("executable");
++    if (executable_path != Py_None)
++    {
++      vtklib = PyUnicode_AsUTF8AndSize(executable_path, nullptr);
++    }
++#else
+     vtklib = vtk_Py_WideToUTF8(Py_GetProgramName());
++#endif
+   }
+   vtklib = systools::CollapseFullPath(vtklib);
+--- /dev/null
++++ vtk9-9.3.0+dfsg1/Utilities/PythonInterpreter/vtkPythonInterpreter.cxx.orig
+@@ -0,0 +1,933 @@
++// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
++// SPDX-License-Identifier: BSD-3-Clause
++#include "vtkPythonInterpreter.h"
++#include "vtkPython.h" // this must be the first include.
++
++#include "vtkBuild.h"
++#include "vtkCommand.h"
++#include "vtkLogger.h"
++#include "vtkNew.h"
++#include "vtkObjectFactory.h"
++#include "vtkOutputWindow.h"
++#include "vtkPythonStdStreamCaptureHelper.h"
++#include "vtkResourceFileLocator.h"
++#include "vtkVersion.h"
++#include "vtkWeakPointer.h"
++#include "vtksys/Encoding.h"
++
++#include <vtksys/Encoding.hxx>
++#include <vtksys/SystemInformation.hxx>
++#include <vtksys/SystemTools.hxx>
++
++#include <algorithm>
++#include <csignal>
++#include <memory>
++#include <sstream>
++#include <string>
++#include <vector>
++
++#if defined(_WIN32) && !defined(__CYGWIN__)
++#define VTK_PATH_SEPARATOR "\\"
++#else
++#define VTK_PATH_SEPARATOR "/"
++#endif
++
++#define VTKPY_DEBUG_MESSAGE(x)                                                                     \
++  vtkVLog(vtkLogger::ConvertToVerbosity(vtkPythonInterpreter::GetLogVerbosity()), x)
++#define VTKPY_DEBUG_MESSAGE_VV(x)                                                                  \
++  vtkVLog(vtkLogger::ConvertToVerbosity(vtkPythonInterpreter::GetLogVerbosity() + 1), x)
++
++#if defined(_WIN32) && !defined(__CYGWIN__) && defined(VTK_BUILD_SHARED_LIBS) &&                   \
++  PY_VERSION_HEX >= 0x03080000
++#define vtkPythonInterpreter_USE_DIRECTORY_COOKIE
++#endif
++
++namespace
++{
++
++template <class T>
++class PoolT
++{
++  std::vector<T*> Strings;
++
++public:
++  ~PoolT()
++  {
++    for (T* astring : this->Strings)
++    {
++      PyMem_RawFree(astring);
++    }
++  }
++
++  T* push_back(T* val)
++  {
++    this->Strings.push_back(val);
++    return val;
++  }
++
++  T* pop_last()
++  {
++    if (this->Strings.empty())
++    {
++      return nullptr;
++    }
++    T* last = *this->Strings.rbegin();
++    this->Strings.pop_back();
++    return last;
++  }
++};
++
++using StringPool = PoolT<char>;
++using WCharStringPool = PoolT<wchar_t>;
++
++wchar_t* vtk_Py_UTF8ToWide(const char* arg)
++{
++  wchar_t* result = nullptr;
++  if (arg != nullptr)
++  {
++    size_t length = vtksysEncoding_mbstowcs(nullptr, arg, 0);
++    if (length > 0)
++    {
++      result = (wchar_t*)PyMem_RawMalloc(sizeof(wchar_t) * (length + 1));
++      vtksysEncoding_mbstowcs(result, arg, length + 1);
++    }
++  }
++
++  return result;
++}
++
++std::string vtk_Py_WideToUTF8(const wchar_t* arg)
++{
++  std::string result;
++  size_t length = vtksysEncoding_wcstombs(nullptr, arg, 0);
++  if (length > 0)
++  {
++    std::vector<char> chars(length + 1);
++    vtksysEncoding_wcstombs(chars.data(), arg, length + 1);
++    result.assign(chars.data(), length);
++  }
++
++  return result;
++}
++
++std::vector<vtkWeakPointer<vtkPythonInterpreter>>* GlobalInterpreters;
++std::vector<std::string> PythonPaths;
++
++void NotifyInterpreters(unsigned long eventid, void* calldata = nullptr)
++{
++  std::vector<vtkWeakPointer<vtkPythonInterpreter>>::iterator iter;
++  for (iter = GlobalInterpreters->begin(); iter != GlobalInterpreters->end(); ++iter)
++  {
++    if (iter->GetPointer())
++    {
++      iter->GetPointer()->InvokeEvent(eventid, calldata);
++    }
++  }
++}
++
++inline void vtkPrependPythonPath(const char* pathtoadd)
++{
++  VTKPY_DEBUG_MESSAGE("adding module search path " << pathtoadd);
++  vtkPythonScopeGilEnsurer gilEnsurer;
++  PyObject* path = PySys_GetObject("path");
++  PyObject* newpath = PyUnicode_FromString(pathtoadd);
++
++  // avoid adding duplicate paths.
++  if (PySequence_Contains(path, newpath) == 0)
++  {
++    PyList_Insert(path, 0, newpath);
++  }
++  Py_DECREF(newpath);
++}
++}
++
++VTK_ABI_NAMESPACE_BEGIN
++// Schwarz counter idiom for GlobalInterpreters object
++static unsigned int vtkPythonInterpretersCounter;
++vtkPythonGlobalInterpreters::vtkPythonGlobalInterpreters()
++{
++  if (vtkPythonInterpretersCounter++ == 0)
++  {
++    GlobalInterpreters = new std::vector<vtkWeakPointer<vtkPythonInterpreter>>();
++  }
++}
++
++vtkPythonGlobalInterpreters::~vtkPythonGlobalInterpreters()
++{
++  if (--vtkPythonInterpretersCounter == 0)
++  {
++    delete GlobalInterpreters;
++    GlobalInterpreters = nullptr;
++  }
++}
++
++bool vtkPythonInterpreter::InitializedOnce = false;
++bool vtkPythonInterpreter::CaptureStdin = false;
++bool vtkPythonInterpreter::RedirectOutput = true;
++bool vtkPythonInterpreter::ConsoleBuffering = false;
++std::string vtkPythonInterpreter::StdErrBuffer;
++std::string vtkPythonInterpreter::StdOutBuffer;
++int vtkPythonInterpreter::LogVerbosity = vtkLogger::VERBOSITY_TRACE;
++
++#if PY_VERSION_HEX >= 0x03000000
++struct CharDeleter
++{
++  void operator()(wchar_t* str) { PyMem_RawFree(str); }
++};
++#endif
++
++vtkStandardNewMacro(vtkPythonInterpreter);
++//------------------------------------------------------------------------------
++vtkPythonInterpreter::vtkPythonInterpreter()
++{
++  GlobalInterpreters->push_back(this);
++}
++
++//------------------------------------------------------------------------------
++vtkPythonInterpreter::~vtkPythonInterpreter()
++{
++  // We need to check that GlobalInterpreters has not been deleted yet. It can be
++  // deleted prior to a call to this destructor if another static object with a
++  // reference to a vtkPythonInterpreter object deletes that object after
++  // GlobalInterpreters has been destructed. It all depends on the destruction order
++  // of the other static object and GlobalInterpreters.
++  if (!GlobalInterpreters)
++  {
++    return;
++  }
++  std::vector<vtkWeakPointer<vtkPythonInterpreter>>::iterator iter;
++  for (iter = GlobalInterpreters->begin(); iter != GlobalInterpreters->end(); ++iter)
++  {
++    if (*iter == this)
++    {
++      GlobalInterpreters->erase(iter);
++      break;
++    }
++  }
++}
++
++//------------------------------------------------------------------------------
++bool vtkPythonInterpreter::IsInitialized()
++{
++  return (Py_IsInitialized() != 0);
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::PrintSelf(ostream& os, vtkIndent indent)
++{
++  this->Superclass::PrintSelf(os, indent);
++}
++
++//------------------------------------------------------------------------------
++bool vtkPythonInterpreter::Initialize(int initsigs /*=0*/)
++{
++  return vtkPythonInterpreter::InitializeWithArgs(initsigs, 0, nullptr);
++}
++
++#if PY_VERSION_HEX >= 0x03080000
++static WCharStringPool PythonProgramName;
++#endif
++
++//------------------------------------------------------------------------------
++// Ensure that Python is pre-initialized enough for VTK to do its
++// initialization. Must be called before any `PyMem_*` calls are made.
++static bool vtkPythonPreConfig()
++{
++  // Guard against doing this multiple times.
++  static bool done = false;
++  if (done)
++  {
++    return false;
++  }
++  done = true;
++
++#if PY_VERSION_HEX >= 0x03080000
++  PyStatus status;
++  PyPreConfig preconfig;
++  PyPreConfig_InitPythonConfig(&preconfig);
++
++  preconfig.allocator = PYMEM_ALLOCATOR_NOT_SET;
++  preconfig.utf8_mode = 1;
++
++  status = Py_PreInitialize(&preconfig);
++  if (PyStatus_Exception(status))
++  {
++    Py_ExitStatusException(status);
++  }
++
++  return preconfig.isolated;
++#else
++  return Py_FrozenFlag;
++#endif
++}
++
++//------------------------------------------------------------------------------
++namespace
++{
++/**
++ * Since vtkPythonInterpreter is often used outside CPython executable, e.g.
++ * vtkpython, the default logic to locate Python standard libraries used by
++ * Python (which depends on the executable path) may fail or pickup incorrect
++ * Python libs. This methods address the issue by setting program name to help
++ * guide Python's default prefix/exec_prefix searching logic.
++ */
++void SetupPythonPrefix(bool isolated)
++{
++  using systools = vtksys::SystemTools;
++
++  // Check if we're using an isolated Python.
++  if (isolated)
++  {
++    VTKPY_DEBUG_MESSAGE("Isolated Python detected; skipping setting up of program path.");
++    return;
++  }
++
++  std::string pythonlib = vtkGetLibraryPathForSymbol(Py_InitializeEx);
++  if (pythonlib.empty())
++  {
++    VTKPY_DEBUG_MESSAGE("static Python build or `Py_InitializeEx` library couldn't be found. "
++                        "Set `PYTHONHOME` if Python standard library fails to load.");
++    return;
++  }
++
++  const std::string newprogramname =
++    systools::GetFilenamePath(pythonlib) + VTK_PATH_SEPARATOR "vtkpython";
++  VTKPY_DEBUG_MESSAGE("calling vtkPythonInterpreter::SetProgramName("
++    << newprogramname << ") to aid in setup of Python prefix.");
++  vtkPythonInterpreter::SetProgramName(newprogramname.c_str());
++}
++
++#ifdef vtkPythonInterpreter_USE_DIRECTORY_COOKIE
++PyObject* DLLDirectoryCookie = nullptr;
++
++void CloseDLLDirectoryCookie()
++{
++  if (DLLDirectoryCookie)
++  {
++    if (PyObject_HasAttrString(DLLDirectoryCookie, "close"))
++    {
++      PyObject* result = PyObject_CallMethod(DLLDirectoryCookie, "close", nullptr);
++      Py_XDECREF(result);
++    }
++    Py_XDECREF(DLLDirectoryCookie);
++    DLLDirectoryCookie = nullptr;
++  }
++}
++#endif
++
++//------------------------------------------------------------------------------
++/**
++ * Add paths to VTK's Python modules.
++ */
++void SetupVTKPythonPaths(bool isolated)
++{
++  // Check if we're using an isolated Python.
++  if (isolated)
++  {
++    VTKPY_DEBUG_MESSAGE("Isolated Python detected; skipping setting up of `vtk` package.");
++    return;
++  }
++
++  using systools = vtksys::SystemTools;
++  std::string vtklib = vtkGetLibraryPathForSymbol(GetVTKVersion);
++  if (vtklib.empty())
++  {
++    VTKPY_DEBUG_MESSAGE(
++      "`GetVTKVersion` library couldn't be found. Will use `Py_GetProgramName` next.");
++  }
++
++  if (vtklib.empty())
++  {
++    vtklib = vtk_Py_WideToUTF8(Py_GetProgramName());
++  }
++
++  vtklib = systools::CollapseFullPath(vtklib);
++  const std::string vtkdir = systools::GetFilenamePath(vtklib);
++
++#if defined(_WIN32) && !defined(__CYGWIN__) && defined(VTK_BUILD_SHARED_LIBS)
++  // On Windows, based on how the executable is run, we end up failing to load
++  // pyd files due to inability to load dependent dlls. This seems to overcome
++  // the issue.
++  if (!vtkdir.empty())
++  {
++#if PY_VERSION_HEX >= 0x03080000
++    vtkPythonScopeGilEnsurer gilEnsurer(false, true);
++    CloseDLLDirectoryCookie();
++    PyObject* os = PyImport_ImportModule("os");
++    if (os)
++    {
++      PyObject* add_dll_directory = PyObject_GetAttrString(os, "add_dll_directory");
++      if (add_dll_directory && PyCallable_Check(add_dll_directory))
++      {
++        PyObject* newpath = PyUnicode_FromString(vtkdir.c_str());
++        DLLDirectoryCookie = PyObject_CallFunctionObjArgs(add_dll_directory, newpath, nullptr);
++        Py_XDECREF(newpath);
++      }
++
++      Py_XDECREF(add_dll_directory);
++    }
++
++    Py_XDECREF(os);
++#else
++    std::string env_path;
++    if (systools::GetEnv("PATH", env_path))
++    {
++      env_path = vtkdir + ";" + env_path;
++    }
++    else
++    {
++      env_path = vtkdir;
++    }
++    systools::PutEnv(std::string("PATH=") + env_path);
++#endif
++  }
++#endif
++
++#if defined(VTK_BUILD_SHARED_LIBS)
++  vtkPythonInterpreter::PrependPythonPath(vtkdir.c_str(), "vtkmodules/__init__.py");
++#else
++  // since there may be other packages not zipped (e.g. mpi4py), we added path to _vtk.zip
++  // to the search path as well.
++  vtkPythonInterpreter::PrependPythonPath(vtkdir.c_str(), "_vtk.zip", /*add_landmark*/ false);
++  vtkPythonInterpreter::PrependPythonPath(vtkdir.c_str(), "_vtk.zip", /*add_landmark*/ true);
++#endif
++}
++}
++
++//------------------------------------------------------------------------------
++bool vtkPythonInterpreter::InitializeWithArgs(int initsigs, int argc, char* argv[])
++{
++  bool isolated = vtkPythonPreConfig();
++
++  if (Py_IsInitialized() == 0)
++  {
++    // guide the mechanism to locate Python standard library, if possible.
++    SetupPythonPrefix(isolated);
++    bool signals_installed = initsigs != 0;
++
++    // Need two copies of args, because programs might modify the first
++    using OwnedWideString = std::unique_ptr<wchar_t, CharDeleter>;
++    std::vector<wchar_t*> argvForPython;
++    std::vector<OwnedWideString> argvCleanup;
++    for (int i = 0; i < argc; i++)
++    {
++      OwnedWideString argCopy(vtk_Py_UTF8ToWide(argv[i]), CharDeleter());
++      if (argCopy == nullptr)
++      {
++        fprintf(stderr,
++          "Fatal vtkpython error: "
++          "unable to decode the command line argument #%i\n",
++          i + 1);
++        return false;
++      }
++
++      argvForPython.push_back(argCopy.get());
++      argvCleanup.emplace_back(std::move(argCopy));
++    }
++    argvForPython.push_back(nullptr);
++
++#if PY_VERSION_HEX < 0x03080000
++    Py_InitializeEx(initsigs);
++    // setup default argv. Without this, code snippets that check `sys.argv` may
++    // fail when run in embedded VTK Python environment.
++    PySys_SetArgvEx(argc, argvForPython.data(), 0);
++
++    isolated = Py_FrozenFlag;
++#else
++    PyConfig config;
++    PyStatus status;
++    PyConfig_InitPythonConfig(&config);
++    config.install_signal_handlers = initsigs;
++    config.program_name = PythonProgramName.pop_last();
++    status = PyConfig_SetArgv(&config, argc, argvForPython.data());
++    if (PyStatus_IsError(status))
++    {
++      PyConfig_Clear(&config);
++      return false;
++    }
++
++    status = Py_InitializeFromConfig(&config);
++    if (PyStatus_IsError(status))
++    {
++      PyConfig_Clear(&config);
++      return false;
++    }
++    isolated = config.pathconfig_warnings == 0;
++    PyConfig_Clear(&config);
++#endif
++
++#ifdef VTK_PYTHON_FULL_THREADSAFE
++#if PY_VERSION_HEX < 0x03090000
++    // In Python 3.9 and higher, PyEval_ThreadsInitialized() and
++    // PyEval_InitThreads() are deprecated and do nothing.
++    // GIL initialization is handled by Py_InitializeEx().
++    int threadInit = PyEval_ThreadsInitialized();
++    if (!threadInit)
++    {
++      PyEval_InitThreads(); // initialize and acquire GIL
++    }
++#endif
++    // Always release GIL, as it has been acquired either by PyEval_InitThreads
++    // prior to Python 3.7 or by Py_InitializeEx in Python 3.7 and after
++    PyEval_SaveThread();
++#endif
++
++#ifdef SIGINT
++    if (signals_installed)
++    {
++      // Put default SIGINT handler back after Py_Initialize/Py_InitializeEx.
++      signal(SIGINT, SIG_DFL);
++    }
++#endif
++  }
++
++  if (!vtkPythonInterpreter::InitializedOnce)
++  {
++    vtkPythonInterpreter::InitializedOnce = true;
++
++    // HACK: Calling PyRun_SimpleString for the first time for some reason results in
++    // a "\n" message being generated which is causing the error dialog to
++    // popup. So we flush that message out of the system before setting up the
++    // callbacks.
++    vtkPythonInterpreter::RunSimpleString("");
++
++    // Redirect Python's stdout and stderr and stdin - GIL protected operation
++    if (vtkPythonInterpreter::RedirectOutput)
++    {
++      // Setup handlers for stdout/stdin/stderr.
++      vtkPythonStdStreamCaptureHelper* wrapperOut = NewPythonStdStreamCaptureHelper(false);
++      vtkPythonStdStreamCaptureHelper* wrapperErr = NewPythonStdStreamCaptureHelper(true);
++      vtkPythonScopeGilEnsurer gilEnsurer;
++      PySys_SetObject("stdout", reinterpret_cast<PyObject*>(wrapperOut));
++      PySys_SetObject("stderr", reinterpret_cast<PyObject*>(wrapperErr));
++      PySys_SetObject("stdin", reinterpret_cast<PyObject*>(wrapperOut));
++      Py_DECREF(wrapperOut);
++      Py_DECREF(wrapperErr);
++    }
++
++    // We call this before processing any of Python paths added by the
++    // application using `PrependPythonPath`. This ensures that application
++    // specified paths are preferred to the ones `vtkPythonInterpreter` adds.
++    SetupVTKPythonPaths(isolated);
++
++    for (size_t cc = 0; cc < PythonPaths.size(); cc++)
++    {
++      vtkPrependPythonPath(PythonPaths[cc].c_str());
++    }
++
++    NotifyInterpreters(vtkCommand::EnterEvent);
++    return true;
++  }
++
++  return false;
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::Finalize()
++{
++  if (Py_IsInitialized() != 0)
++  {
++    NotifyInterpreters(vtkCommand::ExitEvent);
++    vtkPythonScopeGilEnsurer gilEnsurer(false, true);
++#ifdef vtkPythonInterpreter_USE_DIRECTORY_COOKIE
++    CloseDLLDirectoryCookie();
++#endif
++    // Py_Finalize will take care of releasing gil
++    Py_Finalize();
++  }
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::SetProgramName(const char* programname)
++{
++  vtkPythonPreConfig();
++  if (programname)
++  {
++#if PY_VERSION_HEX >= 0x03080000
++    if (wchar_t* argv0 = vtk_Py_UTF8ToWide(programname))
++    {
++      PythonProgramName.push_back(argv0);
++    }
++    else
++    {
++      fprintf(stderr,
++        "Fatal vtkpython error: "
++        "unable to decode the program name\n");
++      wchar_t* empty = (wchar_t*)PyMem_RawMalloc(sizeof(wchar_t));
++      empty[0] = 0;
++      PythonProgramName.push_back(empty);
++    }
++#else
++    // From Python Docs: The argument should point to a zero-terminated character
++    // string in static storage whose contents will not change for the duration of
++    // the program's execution. No code in the Python interpreter will change the
++    // contents of this storage.
++    wchar_t* argv0 = vtk_Py_UTF8ToWide(programname);
++    if (argv0 == nullptr)
++    {
++      fprintf(stderr,
++        "Fatal vtkpython error: "
++        "unable to decode the program name\n");
++      static wchar_t empty[1] = { 0 };
++      argv0 = empty;
++      Py_SetProgramName(argv0);
++    }
++    else
++    {
++      static WCharStringPool wpool;
++      Py_SetProgramName(wpool.push_back(argv0));
++    }
++#endif
++  }
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::PrependPythonPath(const char* dir)
++{
++  if (!dir)
++  {
++    return;
++  }
++
++  std::string out_dir = dir;
++
++#if defined(_WIN32) && !defined(__CYGWIN__)
++  // Convert slashes for this platform.
++  std::replace(out_dir.begin(), out_dir.end(), '/', '\\');
++#endif
++
++  if (Py_IsInitialized() == 0)
++  {
++    // save path for future use.
++    PythonPaths.push_back(out_dir);
++    return;
++  }
++
++  // Append the path to the python sys.path object.
++  vtkPrependPythonPath(out_dir.c_str());
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::PrependPythonPath(
++  const char* anchor, const char* landmark, bool add_landmark)
++{
++  const std::vector<std::string> prefixes = {
++    VTK_PYTHON_SITE_PACKAGES_SUFFIX
++#if defined(__APPLE__)
++    // if in an App bundle, the `sitepackages` dir is <app_root>/Contents/Python
++    ,
++    "Contents/Python"
++#endif
++    ,
++    "."
++  };
++
++  vtkNew<vtkResourceFileLocator> locator;
++  locator->SetLogVerbosity(vtkPythonInterpreter::GetLogVerbosity() + 1);
++  std::string path = locator->Locate(anchor, prefixes, landmark);
++  if (!path.empty())
++  {
++    if (add_landmark)
++    {
++      path = path + "/" + landmark;
++    }
++    vtkPythonInterpreter::PrependPythonPath(path.c_str());
++  }
++}
++
++//------------------------------------------------------------------------------
++int vtkPythonInterpreter::PyMain(int argc, char** argv)
++{
++  vtksys::SystemTools::EnableMSVCDebugHook();
++
++  int count_v = 0;
++  for (int cc = 0; cc < argc; ++cc)
++  {
++    if (argv[cc] && strcmp(argv[cc], "-v") == 0)
++    {
++      ++count_v;
++    }
++    if (argv[cc] && strcmp(argv[cc], "-vv") == 0)
++    {
++      count_v += 2;
++    }
++  }
++
++  if (count_v > 0)
++  {
++    // change the vtkPythonInterpreter's log verbosity. We only touch it
++    // if the command line arguments explicitly requested a certain verbosity.
++    vtkPythonInterpreter::SetLogVerbosity(vtkLogger::VERBOSITY_INFO);
++    vtkLogger::SetStderrVerbosity(vtkLogger::ConvertToVerbosity(count_v - 1));
++  }
++
++  vtkLogger::Init(argc, argv, nullptr); // since `-v` and `-vv` are parsed as Python verbosity flags
++                                        // and not log verbosity flags.
++
++  // Need two copies of args, because the first array may be modified elsewhere.
++  using OwnedCString = std::unique_ptr<char, decltype(&std::free)>;
++  std::vector<char*> argvForPython;
++  std::vector<OwnedCString> argvCleanup;
++  for (int i = 0; i < argc; i++)
++  {
++    if (!argv[i])
++    {
++      continue;
++    }
++    if (strcmp(argv[i], "--enable-bt") == 0)
++    {
++      vtksys::SystemInformation::SetStackTraceOnError(1);
++      continue;
++    }
++    if (strcmp(argv[i], "-V") == 0)
++    {
++      // print out VTK version and let argument pass to Py_RunMain(). At which
++      // point, Python will print its version and exit.
++      cout << vtkVersion::GetVTKSourceVersion() << endl;
++    }
++
++    OwnedCString argCopy(strdup(argv[i]), &std::free);
++    if (argCopy == nullptr)
++    {
++      fprintf(stderr,
++        "Fatal vtkpython error: "
++        "unable to copy the command line argument #%i\n",
++        i + 1);
++      return 1;
++    }
++
++    argvForPython.push_back(argCopy.get());
++    argvCleanup.emplace_back(std::move(argCopy));
++  }
++  int argvForPythonSize = static_cast<int>(argvForPython.size());
++  argvForPython.push_back(nullptr);
++
++  vtkPythonInterpreter::InitializeWithArgs(1, argvForPythonSize, argvForPython.data());
++
++#if PY_VERSION_HEX >= 0x03070000 && PY_VERSION_HEX < 0x03080000
++  // Python 3.7.0 has a bug where Py_InitializeEx (called above) followed by
++  // Py_Main (at the end of this block) causes a crash. Gracefully exit with
++  // failure if we're using 3.7.0 and suggest getting the newest 3.7.x release.
++  // See <https://gitlab.kitware.com/vtk/vtk/-/issues/17434> for details.
++  {
++    bool is_ok = true;
++    vtkPythonScopeGilEnsurer gilEnsurer(false, true);
++    PyObject* sys = PyImport_ImportModule("sys");
++    if (sys)
++    {
++      // XXX: Check sys.implementation.name == 'cpython'?
++
++      PyObject* version_info = PyObject_GetAttrString(sys, "version_info");
++      if (version_info)
++      {
++        PyObject* major = PyObject_GetAttrString(version_info, "major");
++        PyObject* minor = PyObject_GetAttrString(version_info, "minor");
++        PyObject* micro = PyObject_GetAttrString(version_info, "micro");
++
++        auto py_number_cmp = [](PyObject* obj, long expected) {
++          return obj && PyLong_Check(obj) && PyLong_AsLong(obj) == expected;
++        };
++
++        // Only 3.7.0 has this issue. Any failures to get the version
++        // information is OK; we'll just crash later anyways if the version is
++        // bad.
++        is_ok = !py_number_cmp(major, 3) || !py_number_cmp(minor, 7) || !py_number_cmp(micro, 0);
++
++        Py_XDECREF(micro);
++        Py_XDECREF(minor);
++        Py_XDECREF(major);
++      }
++
++      Py_XDECREF(version_info);
++    }
++
++    Py_XDECREF(sys);
++
++    if (!is_ok)
++    {
++      std::cerr << "Python 3.7.0 has a known issue that causes a crash with a "
++                   "specific API usage pattern. This has been fixed in 3.7.1 and all "
++                   "newer 3.7.x Python releases. Exiting now to avoid the crash."
++                << std::endl;
++      return 1;
++    }
++  }
++#endif
++
++#if PY_VERSION_HEX < 0x03080000
++  // Need two copies of args, because programs might modify the first
++  using OwnedWideString = std::unique_ptr<wchar_t, CharDeleter>;
++  std::vector<wchar_t*> argvForPythonWide;
++  std::vector<OwnedWideString> argvCleanupWide;
++  for (size_t i = 0; i < argvCleanup.size(); i++)
++  {
++    OwnedWideString argCopy(vtk_Py_UTF8ToWide(argvCleanup[i].get()), CharDeleter());
++    if (argCopy == nullptr)
++    {
++      fprintf(stderr,
++        "Fatal vtkpython error: "
++        "unable to decode the command line argument #%zu\n",
++        i + 1);
++      return 1;
++    }
++
++    argvForPythonWide.push_back(argCopy.get());
++    argvCleanupWide.emplace_back(std::move(argCopy));
++  }
++  int argvForPythonWideSize = static_cast<int>(argvForPythonWide.size());
++  argvForPythonWide.push_back(nullptr);
++
++  vtkPythonScopeGilEnsurer gilEnsurer(false, true);
++  return Py_Main(argvForPythonWideSize, argvForPythonWide.data());
++#else
++  vtkPythonScopeGilEnsurer gilEnsurer(false, true);
++  return Py_RunMain();
++#endif
++}
++
++//------------------------------------------------------------------------------
++int vtkPythonInterpreter::RunSimpleString(const char* script)
++{
++  vtkPythonInterpreter::Initialize(1);
++  vtkPythonInterpreter::ConsoleBuffering = true;
++
++  // The embedded python interpreter cannot handle DOS line-endings, see
++  // http://sourceforge.net/tracker/?group_id=5470&atid=105470&func=detail&aid=1167922
++  std::string buffer = script ? script : "";
++  buffer.erase(std::remove(buffer.begin(), buffer.end(), '\r'), buffer.end());
++
++  // The cast is necessary because PyRun_SimpleString() hasn't always been const-correct
++  int pyReturn;
++  {
++    vtkPythonScopeGilEnsurer gilEnsurer;
++    pyReturn = PyRun_SimpleString(buffer.c_str());
++  }
++
++  vtkPythonInterpreter::ConsoleBuffering = false;
++  if (!vtkPythonInterpreter::StdErrBuffer.empty())
++  {
++    vtkOutputWindow::GetInstance()->DisplayErrorText(vtkPythonInterpreter::StdErrBuffer.c_str());
++    NotifyInterpreters(
++      vtkCommand::ErrorEvent, const_cast<char*>(vtkPythonInterpreter::StdErrBuffer.c_str()));
++    vtkPythonInterpreter::StdErrBuffer.clear();
++  }
++  if (!vtkPythonInterpreter::StdOutBuffer.empty())
++  {
++    vtkOutputWindow::GetInstance()->DisplayText(vtkPythonInterpreter::StdOutBuffer.c_str());
++    NotifyInterpreters(
++      vtkCommand::SetOutputEvent, const_cast<char*>(vtkPythonInterpreter::StdOutBuffer.c_str()));
++    vtkPythonInterpreter::StdOutBuffer.clear();
++  }
++
++  return pyReturn;
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::SetCaptureStdin(bool val)
++{
++  vtkPythonInterpreter::CaptureStdin = val;
++}
++
++//------------------------------------------------------------------------------
++bool vtkPythonInterpreter::GetCaptureStdin()
++{
++  return vtkPythonInterpreter::CaptureStdin;
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::SetRedirectOutput(bool redirect)
++{
++  vtkPythonInterpreter::RedirectOutput = redirect;
++}
++
++//------------------------------------------------------------------------------
++bool vtkPythonInterpreter::GetRedirectOutput()
++{
++  return vtkPythonInterpreter::RedirectOutput;
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::WriteStdOut(const char* txt)
++{
++  if (vtkPythonInterpreter::ConsoleBuffering)
++  {
++    vtkPythonInterpreter::StdOutBuffer += std::string(txt);
++  }
++  else
++  {
++    vtkOutputWindow::GetInstance()->DisplayText(txt);
++    NotifyInterpreters(vtkCommand::SetOutputEvent, const_cast<char*>(txt));
++  }
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::FlushStdOut() {}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::WriteStdErr(const char* txt)
++{
++  if (vtkPythonInterpreter::ConsoleBuffering)
++  {
++    vtkPythonInterpreter::StdErrBuffer += std::string(txt);
++  }
++  else
++  {
++    vtkOutputWindow::GetInstance()->DisplayErrorText(txt);
++    NotifyInterpreters(vtkCommand::ErrorEvent, const_cast<char*>(txt));
++  }
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::FlushStdErr() {}
++
++//------------------------------------------------------------------------------
++vtkStdString vtkPythonInterpreter::ReadStdin()
++{
++  if (!vtkPythonInterpreter::CaptureStdin)
++  {
++    vtkStdString string;
++    cin >> string;
++    return string;
++  }
++  vtkStdString string;
++  NotifyInterpreters(vtkCommand::UpdateEvent, &string);
++  return string;
++}
++
++//------------------------------------------------------------------------------
++void vtkPythonInterpreter::SetLogVerbosity(int val)
++{
++  vtkPythonInterpreter::LogVerbosity = vtkLogger::ConvertToVerbosity(val);
++}
++
++//------------------------------------------------------------------------------
++int vtkPythonInterpreter::GetLogVerbosity()
++{
++  return vtkPythonInterpreter::LogVerbosity;
++}
++
++#if defined(_WIN32)
++//------------------------------------------------------------------------------
++vtkWideArgsConverter::vtkWideArgsConverter(int argc, wchar_t* wargv[])
++{
++  this->Argc = argc;
++  for (int i = 0; i < argc; i++)
++  {
++    std::string str = vtksys::Encoding::ToNarrow(wargv[i]);
++    char* cstr = vtksys::SystemTools::DuplicateString(str.c_str());
++    Args.push_back(cstr);
++    MemCache.push_back(cstr);
++  }
++  Args.push_back(nullptr);
++}
++
++//------------------------------------------------------------------------------
++vtkWideArgsConverter::~vtkWideArgsConverter()
++{
++  for (auto cstr : MemCache)
++  {
++    delete[] cstr;
++  }
++}
++#endif
++VTK_ABI_NAMESPACE_END
+--- vtk9-9.3.0+dfsg1.orig/Utilities/PythonInterpreter/vtkPythonStdStreamCaptureHelper.h
++++ vtk9-9.3.0+dfsg1/Utilities/PythonInterpreter/vtkPythonStdStreamCaptureHelper.h
+@@ -16,7 +16,8 @@ VTK_ABI_NAMESPACE_BEGIN
+ struct vtkPythonStdStreamCaptureHelper
+ {
+   PyObject_HEAD
+-  int softspace; // Used by print to keep track of its state.
++  int softspace;        // Used by print to keep track of its state.
++  const char* Encoding; // Encoding, set to "utf-8"
+   bool DumpToError;
+   void Write(const char* string)
+@@ -84,6 +85,9 @@ static PyMemberDef vtkPythonStdStreamCap
+   { VTK_PYTHON_MEMBER_DEF_STR("softspace"), T_INT,
+     offsetof(vtkPythonStdStreamCaptureHelper, softspace), 0,
+     VTK_PYTHON_MEMBER_DEF_STR("Placeholder so print can keep state.") },
++  { VTK_PYTHON_MEMBER_DEF_STR("encoding"), T_STRING,
++    offsetof(vtkPythonStdStreamCaptureHelper, Encoding), READONLY,
++    VTK_PYTHON_MEMBER_DEF_STR("Text encoding for file.") },
+   { nullptr, 0, 0, 0, nullptr }
+ };
+@@ -250,6 +254,7 @@ static vtkPythonStdStreamCaptureHelper*
+     PyObject_New(vtkPythonStdStreamCaptureHelper, &vtkPythonStdStreamCaptureHelperType);
+   if (wrapper)
+   {
++    wrapper->Encoding = "utf-8";
+     wrapper->DumpToError = for_stderr;
+   }
+--- vtk9-9.3.0+dfsg1.orig/Wrapping/Python/vtkmodules/test/Testing.py
++++ vtk9-9.3.0+dfsg1/Wrapping/Python/vtkmodules/test/Testing.py
+@@ -515,8 +515,10 @@ def test(cases):
+     """
+     # Make the test suites from the arguments.
+     suites = []
+-    for case in cases:
+-        suites.append(unittest.makeSuite(case[0], case[1]))
++    loader = unittest.TestLoader()
++    # the "name" is ignored (it was always just 'test')
++    for test,name in cases:
++        suites.append(loader.loadTestsFromTestCase(test))
+     test_suite = unittest.TestSuite(suites)
+     # Now run the tests.
+--- vtk9-9.3.0+dfsg1.orig/Wrapping/PythonCore/PyVTKNamespace.cxx
++++ vtk9-9.3.0+dfsg1/Wrapping/PythonCore/PyVTKNamespace.cxx
+@@ -112,8 +112,10 @@ PyObject* PyVTKNamespace_New(const char*
+   {
+     // make sure python has readied the type object
+     PyType_Ready(&PyVTKNamespace_Type);
+-    // call the allocator provided by python for this type
+-    self = PyVTKNamespace_Type.tp_alloc(&PyVTKNamespace_Type, 0);
++    // call the superclass new function
++    PyObject* empty = PyTuple_New(0);
++    self = PyVTKNamespace_Type.tp_base->tp_new(&PyVTKNamespace_Type, empty, nullptr);
++    Py_DECREF(empty);
+     // call the superclass init function
+     PyObject* pyname = PyUnicode_FromString(name);
+     PyObject* args = PyTuple_Pack(1, pyname);
+--- vtk9-9.3.0+dfsg1.orig/Wrapping/PythonCore/PyVTKTemplate.cxx
++++ vtk9-9.3.0+dfsg1/Wrapping/PythonCore/PyVTKTemplate.cxx
+@@ -761,8 +761,10 @@ PyObject* PyVTKTemplate_New(const char*
+ {
+   // make sure python has readied the type object
+   PyType_Ready(&PyVTKTemplate_Type);
+-  // call the allocator provided by python for this type
+-  PyObject* self = PyVTKTemplate_Type.tp_alloc(&PyVTKTemplate_Type, 0);
++  // call the superclass new function
++  PyObject* empty = PyTuple_New(0);
++  PyObject* self = PyVTKTemplate_Type.tp_base->tp_new(&PyVTKTemplate_Type, empty, nullptr);
++  Py_DECREF(empty);
+   // call the superclass init function
+   PyObject* pyname = PyUnicode_FromString(name);
+   PyObject* pydoc = PyUnicode_FromString(docstring);
diff --git a/debian/patches/42_fix_octree_node.patch b/debian/patches/42_fix_octree_node.patch
new file mode 100644 (file)
index 0000000..5956e95
--- /dev/null
@@ -0,0 +1,13 @@
+Description: Fix undefined variable name in octree_node
+
+--- vtk9-9.3.0+dfsg1.orig/Utilities/octree/octree/octree_node.txx
++++ vtk9-9.3.0+dfsg1/Utilities/octree/octree/octree_node.txx
+@@ -210,7 +210,7 @@ const octree_node<T_, d_, A_>& octree_no
+   {
+     throw std::domain_error("Attempt to access children of an octree leaf node.");
+   }
+-  return this->_M_chilren[child];
++  return this->m_children[child];
+ }
+ /**\brief Return a reference to a child node.
diff --git a/debian/patches/netcdf-4.9.3.patch b/debian/patches/netcdf-4.9.3.patch
new file mode 100644 (file)
index 0000000..57aa25c
--- /dev/null
@@ -0,0 +1,172 @@
+Description: Replace _FillValue by NC_FillValue for NetCDF 4.9.3.
+Author: Bas Couwenberg <sebastic@debian.org>
+
+--- a/IO/MINC/vtkMINC.h
++++ b/IO/MINC/vtkMINC.h
+@@ -178,7 +178,7 @@ use it.
+ #define MIvalid_range "valid_range"
+ #define MIvalid_max "valid_max"
+ #define MIvalid_min "valid_min"
+-#define MI_FillValue "_FillValue"
++#define MI_FillValue "NC_FillValue"
+ #define MItitle "title"
+ #define MIhistory "history"
+--- a/IO/NetCDF/vtkNetCDFCFWriter.cxx
++++ b/IO/NetCDF/vtkNetCDFCFWriter.cxx
+@@ -442,7 +442,7 @@ public:
+     status = NC_NOERR;
+     if (std::string(arrayName).rfind("vtk", 0) > 0)
+     {
+-      // for an array that starts with vtk we don't specify _FillValue
++      // for an array that starts with vtk we don't specify NC_FillValue
+       switch (vtkType)
+       {
+         case VTK_CHAR:
+@@ -451,34 +451,34 @@ public:
+           if (fillValue != NC_FILL_INT)
+           {
+             unsigned char fillByte = fillValue;
+-            status = nc_put_att(ncid, attributeid, "_FillValue", NC_BYTE, 1, &fillByte);
++            status = nc_put_att(ncid, attributeid, "NC_FillValue", NC_BYTE, 1, &fillByte);
+           }
+           break;
+         case VTK_SHORT:
+           if (fillValue != NC_FILL_SHORT)
+           {
+             short fillShort = fillValue;
+-            status = nc_put_att_short(ncid, attributeid, "_FillValue", NC_SHORT, 1, &fillShort);
++            status = nc_put_att_short(ncid, attributeid, "NC_FillValue", NC_SHORT, 1, &fillShort);
+           }
+           break;
+         case VTK_INT:
+           if (fillValue != NC_FILL_INT)
+           {
+-            status = nc_put_att_int(ncid, attributeid, "_FillValue", NC_INT, 1, &fillValue);
++            status = nc_put_att_int(ncid, attributeid, "NC_FillValue", NC_INT, 1, &fillValue);
+           }
+           break;
+         case VTK_FLOAT:
+           if (fillValue != NC_FILL_INT)
+           {
+             float fillFloat = fillValue;
+-            status = nc_put_att_float(ncid, attributeid, "_FillValue", NC_FLOAT, 1, &fillFloat);
++            status = nc_put_att_float(ncid, attributeid, "NC_FillValue", NC_FLOAT, 1, &fillFloat);
+           }
+           break;
+         case VTK_DOUBLE:
+           if (fillValue != NC_FILL_INT)
+           {
+             double fillDouble = fillValue;
+-            status = nc_put_att_double(ncid, attributeid, "_FillValue", NC_DOUBLE, 1, &fillDouble);
++            status = nc_put_att_double(ncid, attributeid, "NC_FillValue", NC_DOUBLE, 1, &fillDouble);
+           }
+           break;
+         default:
+@@ -489,7 +489,7 @@ public:
+       if (status)
+       {
+         std::ostringstream ostr;
+-        ostr << "Error nc_put_att_xxx " << arrayName << ":_FillValue: " << nc_strerror(status);
++        ostr << "Error nc_put_att_xxx " << arrayName << ":NC_FillValue: " << nc_strerror(status);
+         throw std::runtime_error(ostr.str());
+       }
+     }
+--- a/IO/NetCDF/vtkNetCDFReader.cxx
++++ b/IO/NetCDF/vtkNetCDFReader.cxx
+@@ -867,7 +867,7 @@ int vtkNetCDFReader::LoadVariable(int nc
+   // Check for a fill value.
+   size_t attribLength;
+-  if ((nc_inq_attlen(ncFD, varId, "_FillValue", &attribLength) == NC_NOERR) && (attribLength == 1))
++  if ((nc_inq_attlen(ncFD, varId, "NC_FillValue", &attribLength) == NC_NOERR) && (attribLength == 1))
+   {
+     if (this->ReplaceFillValueWithNan)
+     {
+@@ -875,7 +875,7 @@ int vtkNetCDFReader::LoadVariable(int nc
+       if (dataArray->GetDataType() == VTK_FLOAT)
+       {
+         float fillValue;
+-        nc_get_att_float(ncFD, varId, "_FillValue", &fillValue);
++        nc_get_att_float(ncFD, varId, "NC_FillValue", &fillValue);
+         std::replace(reinterpret_cast<float*>(dataArray->GetVoidPointer(0)),
+           reinterpret_cast<float*>(dataArray->GetVoidPointer(dataArray->GetNumberOfTuples())),
+           fillValue, static_cast<float>(vtkMath::Nan()));
+@@ -883,7 +883,7 @@ int vtkNetCDFReader::LoadVariable(int nc
+       else if (dataArray->GetDataType() == VTK_DOUBLE)
+       {
+         double fillValue;
+-        nc_get_att_double(ncFD, varId, "_FillValue", &fillValue);
++        nc_get_att_double(ncFD, varId, "NC_FillValue", &fillValue);
+         std::replace(reinterpret_cast<double*>(dataArray->GetVoidPointer(0)),
+           reinterpret_cast<double*>(dataArray->GetVoidPointer(dataArray->GetNumberOfTuples())),
+           fillValue, vtkMath::Nan());
+--- a/IO/NetCDF/vtkNetCDFReader.h
++++ b/IO/NetCDF/vtkNetCDFReader.h
+@@ -107,7 +107,7 @@ public:
+   ///@{
+   /**
+-   * If on, any float or double variable read that has a _FillValue attribute
++   * If on, any float or double variable read that has a NC_FillValue attribute
+    * will have that fill value replaced with a not-a-number (NaN) value.  The
+    * advantage of setting these to NaN values is that, if implemented properly
+    * by the system and careful math operations are used, they can implicitly be
+--- a/IO/NetCDF/vtkNetCDFUGRIDReader.cxx
++++ b/IO/NetCDF/vtkNetCDFUGRIDReader.cxx
+@@ -508,10 +508,10 @@ bool vtkNetCDFUGRIDReader::ParseHeader()
+   if (this->NodesPerFace > 3) // may be mixed mesh
+   {
+     if (!this->CheckError(
+-          nc_get_att(this->NcId, this->FaceVarId, "_FillValue", &this->FaceFillValue)))
++          nc_get_att(this->NcId, this->FaceVarId, "NC_FillValue", &this->FaceFillValue)))
+     {
+-      vtkErrorMacro("_FillValue attribute missing - The connectivity variable has to specify a "
+-                    "_FillValue attribute because it has more than 3 nodes per face");
++      vtkErrorMacro("NC_FillValue attribute missing - The connectivity variable has to specify a "
++                    "NC_FillValue attribute because it has more than 3 nodes per face");
+       return false;
+     }
+   }
+@@ -859,7 +859,7 @@ struct DataArrayExtractor
+     if (replaceFill && (std::is_same<T, float>::value || std::is_same<T, double>::value))
+     {
+       T fillValue{};
+-      if (nc_get_att(NcId, var, "_FillValue", &fillValue) != NC_NOERR)
++      if (nc_get_att(NcId, var, "NC_FillValue", &fillValue) != NC_NOERR)
+       {
+         vtkDebugWithObjectMacro(output, "No fill value defined");
+         return;
+--- a/IO/NetCDF/vtkNetCDFUGRIDReader.h
++++ b/IO/NetCDF/vtkNetCDFUGRIDReader.h
+@@ -76,7 +76,7 @@ public:
+   ///@{
+   /**
+-   * If on, any float or double variable read that has a _FillValue attribute
++   * If on, any float or double variable read that has a NC_FillValue attribute
+    * will have that fill value replaced with a not-a-number (NaN) value.  The
+    * advantage of setting these to NaN values is that, if implemented properly
+    * by the system and careful math operations are used, they can implicitly be
+--- a/ThirdParty/exodusII/vtkexodusII/src/ex_put_prop.c
++++ b/ThirdParty/exodusII/vtkexodusII/src/ex_put_prop.c
+@@ -243,7 +243,7 @@ int ex_put_prop(int exoid, ex_entity_typ
+     vals[0] = 0; /* fill value */
+     /*   create attribute to cause variable to fill with zeros per routine spec
+      */
+-    if ((status = nc_put_att_longlong(exoid, propid, _FillValue, int_type, 1, vals)) != NC_NOERR) {
++    if ((status = nc_put_att_longlong(exoid, propid, NC_FillValue, int_type, 1, vals)) != NC_NOERR) {
+       snprintf(errmsg, MAX_ERR_LENGTH,
+                "ERROR: failed to create property name fill attribute in file id %d", exoid);
+       ex_err_fn(exoid, __func__, errmsg, status);
+--- a/ThirdParty/exodusII/vtkexodusII/src/ex_put_prop_names.c
++++ b/ThirdParty/exodusII/vtkexodusII/src/ex_put_prop_names.c
+@@ -172,7 +172,7 @@ int ex_put_prop_names(int exoid, ex_enti
+     /*   create attribute to cause variable to fill with zeros per routine spec
+      */
+-    if ((status = nc_put_att_longlong(exoid, propid, _FillValue, int_type, 1, vals)) != NC_NOERR) {
++    if ((status = nc_put_att_longlong(exoid, propid, NC_FillValue, int_type, 1, vals)) != NC_NOERR) {
+       snprintf(errmsg, MAX_ERR_LENGTH,
+                "ERROR: failed to create property name fill attribute in file id %d", exoid);
+       ex_err_fn(exoid, __func__, errmsg, status);
index 62197a20e778b021fdfc5fda334c5f1ddee7f807..b3eb0c0fcc632981809c71343732ae2ee13bf651 100644 (file)
@@ -1,7 +1,9 @@
+09_newer_expat.patch
 10_matplotlib.patch
 20_do_not_link_against_socket.patch
 30_drop_medical_example.patch
 40_vtkpython-9.patch
+42_fix_octree_node.patch
 50_fix_python-modules_path.patch
 60_fix_path_perl.patch
 84_vtkQWidgetTexture_no_vtkOpenGLCheckErrorMacro.patch
@@ -10,3 +12,6 @@
 98_fix_mpi4py.py
 99_fix_ftbfs.patch
 100_add_missing_gl_header.patch
+121_add_support_for_loong64.patch
+130_fix_python_3.13.patch
+netcdf-4.9.3.patch
index 7f3a1be5273af684e2413ce2413f841e124c3218..a607f6af7a38257105139f94ad654a7f332e04da 100755 (executable)
@@ -1,10 +1,11 @@
 #!/usr/bin/make -f
 BUILDDIR = $(CURDIR)/debian/build
 
-DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
+include /usr/share/dpkg/architecture.mk
 
-nojava_archs=hppa hurd-i386 kfreebsd-i386 kfreebsd-amd64
-ifneq ($(DEB_BUILD_ARCH),$(filter $(DEB_BUILD_ARCH), $(nojava_archs)))
+nojava_archs=hppa
+nojava_os=hurd
+ifeq (,$(filter $(DEB_BUILD_ARCH), $(nojava_archs))$(filter $(DEB_BUILD_ARCH_OS), $(nojava_os)))
   export JAVA_HOME=/usr/lib/jvm/default-java
   extra_flags += -DVTK_WRAP_JAVA=ON
 endif
@@ -14,8 +15,9 @@ ifneq (,$(filter $(DEB_HOST_ARCH), armel m68k mips mipsel powerpc sh4))
   export DEB_LDFLAGS_MAINT_APPEND += -Wl,--no-as-needed -latomic -Wl,--as-needed
 endif
 
-notbb_archs=hurd-i386 kfreebsd-i386 kfreebsd-amd64
-ifneq ($(DEB_BUILD_ARCH),$(filter $(DEB_BUILD_ARCH), $(notbb_archs)))
+notbb_archs=
+notbb_os=hurd
+ifeq (,$(filter $(DEB_BUILD_ARCH), $(notbb_archs))$(filter $(DEB_BUILD_ARCH_OS), $(notbb_os)))
   extra_flags += -DVTK_SMP_IMPLEMENTATION_TYPE:STRING="TBB"
 else
   extra_flags += -DVTK_SMP_IMPLEMENTATION_TYPE:STRING="OpenMP"
@@ -45,6 +47,7 @@ extra_flags +=  \
        -DVTK_GROUP_ENABLE_Views:STRING="YES" \
        -DVTK_GROUP_ENABLE_MPI:STRING="YES" \
        -DVTK_GROUP_ENABLE_Imaging:STRING="YES" \
+       -DVTK_MODULE_ENABLE_VTK_IOGeoJSON:STRING="YES" \
        -DVTK_MODULE_ENABLE_VTK_RenderingQt:STRING="YES" \
        -DVTK_MODULE_ENABLE_VTK_RenderingTk:STRING="YES" \
        -DVTK_MODULE_ENABLE_VTK_utf8:STRING="YES" \
@@ -71,8 +74,7 @@ extra_flags +=  \
        -DVTK_MODULE_USE_EXTERNAL_VTK_tiff:BOOL=ON \
        -DVTK_MODULE_USE_EXTERNAL_VTK_utf8:BOOL=ON \
        -DVTK_MODULE_USE_EXTERNAL_VTK_zlib:BOOL=ON \
-       -DVTK_PYTHON_VERSION:STRING=3 \
-       -DVTK_USE_TK=ON \
+       -DVTK_USE_TK=OFF \
        -DVTK_WRAP_PYTHON=ON \
        -DVTK_MODULE_ENABLE_VTK_RenderingContextOpenGL2=YES \
        -DCMAKE_BUILD_TYPE=RelWithDebInfo \